#pragma once
#include <iostream>
#include <string>

#include <cstdio>
#include <cstdarg>
#include <unistd.h>
#define LOG_NORMAL "log.txt"
#define LOG_ERROR "logerr.txt"

// 日志有不同的等级
#define DEBUG 0
#define NORMAL 1
#define WARNING 2
#define ERROR 3
#define FATAL 4

const char *to_levelstr(const int &level)
{
    switch (level)
    {
    case 0:
        return "DEBUG";
    case 1:
        return "NORMAL";
    case 2:
        return "WARNING";
    case 3:
        return "ERROR";
    case 4:
        return "FATAL";
    default:
        return "???";
    }
}

//...为可变参数列表
// LogMessage(NORMAL, "creat listensocket success:%d %c %d", _listensockfd, 'C', 12);
void LogMessage(int level, const char *format, ...)
{
    // [日志等级][日志时间][日志pid][message]
    // std::cout << level << " " << message << std::endl;
    // 使用vprintf

    // 1.获取日志格式化消息message
#define NUM 1024
    char message[NUM];

    va_list arg;           // 定义va_list获取可变参数列表,format是我们的格式化部分
    va_start(arg, format); // 由于函数参数压栈是从右往左，所以va_start获取可变参数列表...直到format停止

    // 将格式化部分format的数据根据arg中的参数列表写入到buffer中
    vsnprintf(message, sizeof(message) - 1, format, arg);

    // 2.根据[日志等级][日志时间][日志pid][message] 打印日志
    time_t currenttime = time(0);
    struct tm *curtm = localtime(&currenttime);
    char cm[64]; // 不可以定义为 char *cm然后写入数据，否则会导致段错误
    sprintf(cm, "%d/%d/%d-%d:%d:%d", curtm->tm_year + 1900, curtm->tm_mon + 1, curtm->tm_mday, curtm->tm_hour, curtm->tm_min, curtm->tm_sec);

    char logprefix[NUM];
    snprintf(logprefix, sizeof(logprefix) - 1, "[%s] [%s] [pid:%d] ", to_levelstr(level), cm, getpid());

    std::cout << logprefix << message << std::endl;
}
